package cn.iocoder.yudao.module.crossborder.platform.service.provider.amazon.client;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.auth.signer.Aws4Signer;
import software.amazon.awssdk.auth.signer.params.Aws4SignerParams;
import software.amazon.awssdk.http.SdkHttpFullRequest;
import software.amazon.awssdk.http.SdkHttpMethod;
import software.amazon.awssdk.regions.Region;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.net.URI;
import java.time.Duration;
import java.time.Instant;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * Amazon SP-API客户端
 * 实现Amazon Selling Partner API的HTTP请求和AWS签名认证
 *
 * @author 芋道源码
 */
@Component
@Slf4j
public class AmazonApiClient {

    // Amazon SP-API 基础URL (北美区域)
    private static final String AMAZON_API_BASE_URL = "https://sellingpartnerapi-na.amazon.com";

    // 请求重试次数
    private static final int MAX_RETRY_COUNT = 3;

    // 请求超时时间
    private static final Duration REQUEST_TIMEOUT = Duration.ofSeconds(30);

    @Value("${amazon.api.access-key:}")
    private String accessKey;

    @Value("${amazon.api.secret-key:}")
    private String secretKey;

    @Value("${amazon.api.region:us-east-1}")
    private String region;

    @Value("${amazon.api.mock.enabled:false}")
    private boolean mockEnabled;

    @Autowired(required = false)
    private AmazonApiMockService amazonApiMockService;

    private OkHttpClient httpClient;
    private ObjectMapper objectMapper;
    private Aws4Signer signer;

    @PostConstruct
    public void init() {
        // 初始化HTTP客户端
        this.httpClient = new OkHttpClient.Builder()
                .connectTimeout(REQUEST_TIMEOUT.getSeconds(), TimeUnit.SECONDS)
                .readTimeout(REQUEST_TIMEOUT.getSeconds(), TimeUnit.SECONDS)
                .writeTimeout(REQUEST_TIMEOUT.getSeconds(), TimeUnit.SECONDS)
                .retryOnConnectionFailure(true)
                .addInterceptor(new LoggingInterceptor())
                .build();

        // 初始化JSON处理器
        this.objectMapper = new ObjectMapper();
        this.objectMapper.findAndRegisterModules();

        // 初始化AWS签名器
        this.signer = Aws4Signer.create();

        log.info("Amazon API客户端初始化完成");
    }

    /**
     * 发送GET请求
     *
     * @param endpoint API端点
     * @param queryParams 查询参数
     * @param accessToken 访问令牌
     * @return 响应结果
     */
    public Map<String, Object> get(String endpoint, Map<String, String> queryParams, String accessToken) {
        log.debug("发送Amazon GET请求: endpoint={}", endpoint);

        // 如果启用模拟模式，使用模拟服务
        if (mockEnabled && amazonApiMockService != null) {
            return handleMockRequest("GET", endpoint, queryParams, null);
        }

        return executeWithRetry(() -> {
            // 1. 构建请求URL
            String url = buildUrl(endpoint, queryParams);

            // 2. 创建请求
            Request.Builder requestBuilder = new Request.Builder()
                    .url(url)
                    .get();

            // 3. 添加认证头
            addAuthHeaders(requestBuilder, endpoint, "GET", null, accessToken);

            // 4. 发送请求
            Request request = requestBuilder.build();
            return executeRequest(request);
        }, endpoint);
    }

    /**
     * 发送POST请求
     *
     * @param endpoint API端点
     * @param body 请求体
     * @param headers 请求头
     * @param accessToken 访问令牌
     * @return 响应结果
     */
    public Map<String, Object> post(String endpoint, Object body, Map<String, String> headers, String accessToken) {
        log.debug("发送Amazon POST请求: endpoint={}", endpoint);

        // 如果启用模拟模式，使用模拟服务
        if (mockEnabled && amazonApiMockService != null) {
            return handleMockRequest("POST", endpoint, null, body);
        }

        return executeWithRetry(() -> {
            // 1. 构建请求URL
            String url = buildUrl(endpoint, null);

            // 2. 序列化请求体
            String jsonBody = null;
            if (body != null) {
                try {
                    jsonBody = objectMapper.writeValueAsString(body);
                } catch (Exception e) {
                    throw new RuntimeException("序列化请求体失败", e);
                }
            }

            // 3. 创建请求
            RequestBody requestBody = jsonBody != null ?
                RequestBody.create(jsonBody, MediaType.get("application/json")) :
                RequestBody.create("", MediaType.get("application/json"));

            Request.Builder requestBuilder = new Request.Builder()
                    .url(url)
                    .post(requestBody);

            // 4. 添加认证头
            addAuthHeaders(requestBuilder, endpoint, "POST", jsonBody, accessToken);

            // 5. 添加自定义头
            if (headers != null) {
                headers.forEach(requestBuilder::addHeader);
            }

            // 6. 发送请求
            Request request = requestBuilder.build();
            return executeRequest(request);
        }, endpoint);
    }

    /**
     * 构建完整的URL
     */
    private String buildUrl(String endpoint, Map<String, String> queryParams) {
        StringBuilder url = new StringBuilder(AMAZON_API_BASE_URL);
        if (!endpoint.startsWith("/")) {
            url.append("/");
        }
        url.append(endpoint);

        if (queryParams != null && !queryParams.isEmpty()) {
            url.append("?");
            queryParams.forEach((key, value) -> {
                if (value != null) {
                    url.append(key).append("=").append(value).append("&");
                }
            });
            // 移除最后的&
            if (url.charAt(url.length() - 1) == '&') {
                url.setLength(url.length() - 1);
            }
        }

        return url.toString();
    }

    /**
     * 添加认证头
     */
    private void addAuthHeaders(Request.Builder requestBuilder, String endpoint, String method,
                               String body, String accessToken) {
        try {
            // 1. 基础头信息
            requestBuilder.addHeader("x-amz-access-token", accessToken);
            requestBuilder.addHeader("Content-Type", "application/json");
            requestBuilder.addHeader("User-Agent", "YudaoCloud/1.0");

            // 2. AWS签名认证 (如果配置了AWS凭证)
            if (accessKey != null && !accessKey.isEmpty() && secretKey != null && !secretKey.isEmpty()) {
                addAwsSignature(requestBuilder, endpoint, method, body);
            }

        } catch (Exception e) {
            log.error("添加认证头失败: endpoint={}", endpoint, e);
            throw new RuntimeException("认证失败", e);
        }
    }

    /**
     * 添加AWS签名
     */
    private void addAwsSignature(Request.Builder requestBuilder, String endpoint, String method, String body) {
        try {
            // 构建AWS请求
            SdkHttpFullRequest.Builder awsRequestBuilder = SdkHttpFullRequest.builder()
                    .method(SdkHttpMethod.fromValue(method))
                    .uri(URI.create(AMAZON_API_BASE_URL + endpoint))
                    .putHeader("Content-Type", "application/json");

            if (body != null) {
                awsRequestBuilder.contentStreamProvider(() ->
                    new java.io.ByteArrayInputStream(body.getBytes()));
            }

            SdkHttpFullRequest awsRequest = awsRequestBuilder.build();

            // 签名参数
            Aws4SignerParams signerParams = Aws4SignerParams.builder()
                    .awsCredentials(AwsBasicCredentials.create(accessKey, secretKey))
                    .signingName("execute-api")
                    .signingRegion(Region.of(region))
                    .build();

            // 执行签名
            SdkHttpFullRequest signedRequest = signer.sign(awsRequest, signerParams);

            // 添加签名头
            signedRequest.headers().forEach((name, values) -> {
                if (name.toLowerCase().startsWith("authorization") ||
                    name.toLowerCase().startsWith("x-amz-")) {
                    values.forEach(value -> requestBuilder.addHeader(name, value));
                }
            });

        } catch (Exception e) {
            log.warn("AWS签名失败，将使用基础认证: {}", e.getMessage());
        }
    }

    /**
     * 执行HTTP请求
     */
    private Map<String, Object> executeRequest(Request request) throws IOException {
        try (Response response = httpClient.newCall(request).execute()) {
            String responseBody = response.body() != null ? response.body().string() : "";

            Map<String, Object> result = new HashMap<>();
            result.put("success", response.isSuccessful());
            result.put("statusCode", response.code());
            result.put("headers", response.headers().toMultimap());

            if (response.isSuccessful()) {
                // 解析JSON响应
                if (responseBody != null && !responseBody.isEmpty()) {
                    try {
                        Map<String, Object> data = objectMapper.readValue(responseBody,
                            new TypeReference<Map<String, Object>>() {});
                        result.put("data", data);
                    } catch (Exception e) {
                        result.put("data", responseBody);
                    }
                }
            } else {
                result.put("error", responseBody);
                log.error("Amazon API请求失败: status={}, body={}", response.code(), responseBody);
            }

            return result;
        }
    }

    /**
     * 带重试的请求执行
     */
    private Map<String, Object> executeWithRetry(RequestExecutor executor, String endpoint) {
        Exception lastException = null;

        for (int attempt = 1; attempt <= MAX_RETRY_COUNT; attempt++) {
            try {
                return executor.execute();
            } catch (Exception e) {
                lastException = e;
                log.warn("Amazon API请求失败 (尝试 {}/{}): endpoint={}, error={}",
                    attempt, MAX_RETRY_COUNT, endpoint, e.getMessage());

                if (attempt < MAX_RETRY_COUNT) {
                    // 指数退避
                    try {
                        Thread.sleep(1000L * attempt);
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt();
                        break;
                    }
                }
            }
        }

        log.error("Amazon API请求最终失败: endpoint={}", endpoint, lastException);
        Map<String, Object> errorResult = new HashMap<>();
        errorResult.put("success", false);
        errorResult.put("error", lastException.getMessage());
        return errorResult;
    }

    /**
     * 请求执行器接口
     */
    @FunctionalInterface
    private interface RequestExecutor {
        Map<String, Object> execute() throws Exception;
    }

    /**
     * 日志拦截器
     */
    private static class LoggingInterceptor implements Interceptor {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();
            long startTime = System.currentTimeMillis();

            log.debug("发送HTTP请求: {} {}", request.method(), request.url());

            Response response = chain.proceed(request);
            long endTime = System.currentTimeMillis();

            log.debug("收到HTTP响应: {} {} - {} ({}ms)",
                request.method(), request.url(), response.code(), endTime - startTime);

            return response;
        }
    }

    /**
     * 处理模拟请求
     */
    private Map<String, Object> handleMockRequest(String method, String endpoint, Map<String, String> queryParams, Object body) {
        log.info("使用模拟模式处理Amazon API请求: {} {}", method, endpoint);

        try {
            // 根据端点路由到不同的模拟方法
            if (endpoint.contains("/orders/v0/orders")) {
                if (endpoint.matches(".*/orders/v0/orders/[^/]+/orderItems")) {
                    // 获取订单商品
                    String orderId = extractOrderIdFromPath(endpoint);
                    return amazonApiMockService.mockGetOrderItems(orderId);
                } else if (endpoint.matches(".*/orders/v0/orders/[^/]+")) {
                    // 获取单个订单
                    String orderId = extractOrderIdFromPath(endpoint);
                    return amazonApiMockService.mockGetOrder(orderId);
                } else {
                    // 获取订单列表
                    return amazonApiMockService.mockGetOrders(queryParams);
                }
            } else if (endpoint.contains("/catalog/v0/items")) {
                if (endpoint.matches(".*/catalog/v0/items/[^/]+")) {
                    // 获取单个商品
                    String asin = extractAsinFromPath(endpoint);
                    return amazonApiMockService.mockGetCatalogItem(asin);
                } else {
                    // 获取商品列表
                    return amazonApiMockService.mockGetCatalogItems(queryParams);
                }
            } else if (endpoint.contains("/fba/inventory/v1/summaries")) {
                // 获取库存汇总
                return amazonApiMockService.mockGetInventorySummaries(queryParams);
            } else if (endpoint.contains("/health")) {
                // 健康检查
                return amazonApiMockService.mockHealthCheck();
            } else if (endpoint.contains("/user/profile")) {
                // 用户配置文件
                return amazonApiMockService.mockGetUserProfile();
            } else {
                // 默认成功响应
                Map<String, Object> response = new HashMap<>();
                response.put("success", true);
                response.put("message", "Mock response for " + endpoint);
                response.put("timestamp", Instant.now().toString());
                return response;
            }
        } catch (Exception e) {
            log.error("模拟请求处理失败: {} {}", method, endpoint, e);
            Map<String, Object> errorResponse = new HashMap<>();
            errorResponse.put("success", false);
            errorResponse.put("error", "Mock request failed: " + e.getMessage());
            return errorResponse;
        }
    }

    /**
     * 从路径中提取订单ID
     */
    private String extractOrderIdFromPath(String path) {
        String[] parts = path.split("/");
        for (int i = 0; i < parts.length; i++) {
            if ("orders".equals(parts[i]) && i + 1 < parts.length) {
                return parts[i + 1];
            }
        }
        return "MOCK-ORDER-" + System.currentTimeMillis();
    }

    /**
     * 从路径中提取ASIN
     */
    private String extractAsinFromPath(String path) {
        String[] parts = path.split("/");
        for (int i = 0; i < parts.length; i++) {
            if ("items".equals(parts[i]) && i + 1 < parts.length) {
                return parts[i + 1];
            }
        }
        return "B" + String.format("%09d", System.currentTimeMillis() % 1000000000);
    }
}
